﻿using Linq2Rest.Provider;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Xinchen.DbUtils;
using Xinchen.SOA.Manager.Api.Contracts;
using Xinchen.Utils;

namespace Xinchen.SOA.Client
{
    public class ApplicationClient : Singleton<ApplicationClient>
    {
        IApplicationSerivce BuildService()
        {
            var _service = ServiceBuilder.BuildService<IApplicationSerivce>(ServiceConsts.ServiceUrl, ServiceConsts.ApplicationServiceName);
            return _service;
        }

        public IQueryable<ApplicationServiceInfo> GetApplicationServices()
        {
            return BuildService().GetApplicationServices();
        }

        public PageResult<ApplicationServiceInfo> GetApplicationServices(int applicationId, int page, int pageSize,
            IList<SqlFilter> filters)
        {
            return BuildService().GetApplicationServices().Where(x => x.ApplicationId == applicationId)
                .Where(filters).Page(page, pageSize);
        }
        public IList<ApplicationServiceInfo> GetApplicationServices(params int[] applicationIds)
        {
            var query = BuildService().GetApplicationServices().Where(x => applicationIds.Contains(x.ApplicationId));
            return query.ToList();
        }



        public List<ApplicationInfo> GetApplications(params int[] applicationIds)
        {
            var query = BuildService().GetApplications();
            if (applicationIds.Any())
            {
                query = query.Where(x => applicationIds.Contains(x.Id));
            }
            return query.ToList();
        }

        public bool VerifyApplication(int applicationId, string applicationKey)
        {
            var _service = BuildService();
            using (_service as IDisposable)
            {
                var result = _service.VerifyApplication(applicationId, applicationKey);
                if (result.ResultCode != 0)
                {
                    throw new ApplicationException(result.ResultMessage);
                }
                return result.IsOk;
            }
        }

        public PageResult<ApplicationServiceActionInfo> GetApplicationServiceActions(int applicationId,
            int serviceId, int page, int pageSize, IList<SqlFilter> filters)
        {
            return GetApplicationServiceActionQuery(applicationId, serviceId, filters).Page(page, pageSize);
        }

        IQueryable<ApplicationServiceActionInfo> GetApplicationServiceActionQuery(
            int applicationId,
            int serviceId,
            IList<SqlFilter> filters)
        {
            var service = BuildService();
            return service.GetApplicationServiceActions().
                Where(x => x.ServiceId == serviceId && x.ApplicationId == applicationId).Where(filters);
        }
        IQueryable<ApplicationServiceActionInfo> GetApplicationServiceActionQuery(
            int applicationServiceId,
            IList<SqlFilter> filters)
        {
            var service = BuildService();
            return service.GetApplicationServiceActions().
                Where(x => x.ApplicationServiceId == applicationServiceId).Where(filters);
        }

        public IList<ApplicationServiceActionInfo> GetApplicationServiceActions(
            int applicationServiceId,
            IList<SqlFilter> filters)
        {
            return GetApplicationServiceActionQuery(applicationServiceId, filters).ToList();
        }
        public PageResult<ApplicationServiceActionInfo> GetApplicationServiceActions(
            int applicationServiceId, int page, int pageSize,
            IList<SqlFilter> filters)
        {
            return GetApplicationServiceActionQuery(applicationServiceId, filters).Page(page, pageSize);
        }
        public IList<ApplicationServiceActionInfo> GetApplicationServiceActions(
            int applicationId,
            int serviceId,
            IList<SqlFilter> filters)
        {
            return GetApplicationServiceActionQuery(applicationId, serviceId, filters).ToList();
        }
        public ApplicationInfo GetApplication(int applicationId)
        {
            return BuildService().GetApplications().FirstOrDefault(x => x.Id == applicationId);
        }
        public PageResult<ApplicationInfo> GetApplications(int page, int pageSize, IList<SqlFilter> filters)
        {
            return BuildService().GetApplications().Where(filters).Page(page, pageSize);
        }

        public ApplicationInfo GetApplication(string applicationName)
        {
            return BuildService().GetApplications().FirstOrDefault(x => x.Name == applicationName);
        }
        public List<ApplicationInfo> SearchApplications(string applicationName)
        {
            return BuildService().GetApplications().Where(x => x.Name.Contains(applicationName)).ToList();
        }

        public void AddApplication(AddApplicationRequest request)
        {
            var service = BuildService();
            using (service as IDisposable)
            {
                var result = service.AddApplication(request);
                if (result.ResultCode != 0)
                {
                    throw new ApplicationException(result.ResultMessage);
                }
            }
        }

        public void UpdateApplication(UpdateApplicationRequest request)
        {
            var service = BuildService();
            using (service as IDisposable)
            {
                var result = service.UpdateApplication(request);
                if (result.ResultCode != 0)
                {
                    throw new ApplicationException(result.ResultMessage);
                }
            }
        }

        public void RemoveApplications(params int[] ids)
        {
            var service = BuildService();
            using (service as IDisposable)
            {
                var result = service.RemoveApplications(new RemoveApplicationRequest()
                {
                    Ids = ids
                });
                if (result.ResultCode != 0)
                {
                    throw new ApplicationException(result.ResultMessage);
                }
            }
        }


        public void RemoveApplicationSerivces(params int[] idArray)
        {
            var service = BuildService();
            using (service as IDisposable)
            {
                var result = service.RemoveApplicationServices(new RemoveApplicationServicesRequest()
                {
                    Ids = idArray
                });
                if (result.ResultCode != 0)
                {
                    throw new ApplicationException(result.ResultMessage);
                }
            }
        }

        public void AddApplicationServices(int applicationId, params int[] serviceIds)
        {
            var service = BuildService();
            using (service as IDisposable)
            {
                var result = service.AddApplicationServices(new AddApplicationServicesRequest()
                {
                    ApplicationId = applicationId,
                    ServiceIds = serviceIds
                });
                if (result.ResultCode != 0)
                {
                    throw new ApplicationException(result.ResultMessage);
                }
            }
        }

        public void AddApplicationServiceActions(int applicationServiceId, params int[] serviceActionIds)
        {
            var service = BuildService();
            using (service as IDisposable)
            {
                var result = service.AddApplicationServiceActions(new AddApplicationServiceActionsRequest()
                {
                    ServiceActionIds = serviceActionIds,
                    ApplicationServiceId = applicationServiceId
                });
                if (result.ResultCode != 0)
                {
                    throw new ApplicationException(result.ResultMessage);
                }
            }
        }
    }
}
